import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Inject, Injectable } from '@nestjs/common';
import { randomBytes } from 'crypto';
import { Cache } from 'cache-manager';
import { SmsService } from './sms.service';

@Injectable()
export class CodeService {
  constructor(
    @Inject(CACHE_MANAGER)
    private readonly cache: Cache,
    private readonly smsService: SmsService,
  ) {}

  private delCode(key) {
    return this.cache.del(key);
  }

  /**
   * 缓存验证码
   * @param key 键名
   * @param value 键值
   * @returns 缓存结果
   */
  private setCode(key: string, value: string) {
    return this.cache.set(key, value, 900);
  }

  /**
   * 读取验证码
   * @param key 键名
   * @returns
   */
  private getCode(key: string) {
    return this.cache.get(key);
  }

  /**
   * 生成验证码
   * @param len 验证码长度
   */
  private genCode(len: number = 6): string {
    const bytes = randomBytes(len);
    const code = bytes.readUIntBE(0, 3) % 1000000;
    return code.toString().padStart(6, '0');
  }

  async issue(phone: string, scene: string) {
    const code = this.genCode();
    // 这里应该有个短信呢
    await this.setCode(`${phone}_${scene}`, code);
    await this.smsService.pushCodeSmsQueue(phone, code);
  }

  async audit(phone: string, scene: string, code: string): Promise<boolean> {
    const key = `${phone}_${scene}`;
    const record = await this.getCode(key);
    if (record && record === code) {
      await this.delCode(key);
      return true;
    }
    return false;
  }
}
